/**
 * 作者：
 * 创建时间：2012-6-25 上午11:50:44
 */
package dragon.model.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import dragon.core.db.DML;
import dragon.core.exception.EasyUIDataLoadException;
import dragon.core.exception.ExceptionHandler;
import dragon.core.page.Page;
import dragon.core.util.GlobalParameter;
import dragon.core.util.Handler;
import dragon.core.util.StringUtils;
import dragon.model.bizObject.BizObject;
import dragon.model.bizObject.BizObjectContainer;
import dragon.model.bizObject.BizObjectDataService;
import dragon.model.bizObject.Connector;
import dragon.model.bizObject.QueryField;
import dragon.model.fieldTemplate.FieldTemplate;
import dragon.model.fieldTemplate.FieldTemplateContainer;
import dragon.model.intercept.Interceptor;

/**
 * 实现功能：
 */
public class BizObjectHandler extends Handler {

	/**
	 * 日志对象
	 */
	Logger logger = LoggerFactory.getLogger(BizObjectHandler.class);

	/**
	 * 数据处理对象
	 */
	BizObjectDataService service = new BizObjectDataService();

	/**
	 * 默认方法
	 * 
	 * @throws ExceptionHandler
	 */
	public String request() throws ExceptionHandler {
		String bizCode = getParameter("bizCode");
		BizObject bizObject = BizObjectContainer.get(bizCode);

		// 渲染list类型，true 标准数据列表模板
		String list = getParameter("list");

		String target = GlobalParameter.MODEL_NOT_FOUND;
		if (bizObject != null) {

			if (bizObject.getIsActive() == 0) {
				throw new ExceptionHandler(String.format("业务模型%s[%s]尚未启用！", bizObject.getName(), bizObject.getCode()));
			}

			// 绑定对象
			setAttribute("bizObject", bizObject);

			// 重定向到JSP页面
			if ("true".equalsIgnoreCase(list)) {
				target = bizObject.getListPage();
			} else {
				target = bizObject.getTreePage();// 默认采用树形
				if (target == null || StringUtils.isEmpty(target)) {
					target = bizObject.getListPage();// 不存在 TREE 模板时，则采用 LIST 模板
				}
			}

			if (target == null || StringUtils.isEmpty(target)) {
				throw new ExceptionHandler(String.format("业务模型%s[%s] 未定义 LISTPAGE 或 TREELISTPAGE ！", bizObject.getName(), bizObject.getCode()));
			}

			bizObject = null;
		} else {
			setAttribute("bizCode", bizCode);
		}

		bizCode = null;

		if (GlobalParameter.PAGES.containsKey(target)) {
			return (String) GlobalParameter.PAGES.get(target);
		} else {
			return target;
		}

	}

	/**
	 * 加载数据
	 * 
	 * @throws ExceptionHandler
	 */
	@SuppressWarnings("unchecked")
	public void loadData() throws EasyUIDataLoadException {
		String bizCode = getParameter("bizCode");
		BizObject bizObject = null;
		try {
			bizObject = BizObjectContainer.get(bizCode);
		} catch (ExceptionHandler e) {
			throw new EasyUIDataLoadException(e);
		}

		Map<String, String> parameterMap = null;
		try {
			parameterMap = getParameterMap();
		} catch (ExceptionHandler e) {
			throw new EasyUIDataLoadException(e);
		}

		// loadData前置动作 beforeLoadData
		int result = Interceptor.INCLUDE_ALL;
		Interceptor interceptor = bizObject.getInterceptor();
		if (interceptor != null) {
			if (logger.isDebugEnabled()) {
				logger.debug(String.format("调用业务模型 %s[%s] 中拦截器类 %s 的 beforeLoadData 方法", bizObject.getName(), bizObject.getCode(), bizObject.getInterceptor()));
			}
			try {
				result = interceptor.beforeLoadData(bizObject, parameterMap, getServerInterface());
			} catch (ExceptionHandler e) {
				throw new EasyUIDataLoadException(e);
			}
		}

		// 执行默认的 loadData 动作
		if (result == Interceptor.INCLUDE_DEFAULT || result == Interceptor.INCLUDE_ALL) {
			String itemsPerPage = getParameter("rows");// 每页显示数据条数
			String targetPage = getParameter("page");// 目标页码
			String sql = bizObject.getSelectSQL();

			// 判断业务模型是否存在记录集查询语句
			if (sql == null || StringUtils.isEmpty(sql)) {
				throw new EasyUIDataLoadException(String.format("业务模型[%s-%s]缺少有效的select语句!", bizObject.getName(), bizObject.getCode()));
			}

			/* 组织查询条件 */
			if (logger.isDebugEnabled()) {
				logger.debug("[SQL]处理前：" + sql);
			}

			String code = null;// 查询字段code，当没有定义cause语句时，用此字段动态拼接语句
			String group = null;// 查询条件分组
			String paramValue = null;// 参数值
			String clause = null;// 自定义查询语句
			String defaultClause = null;// 默认的自定义查询语句
			Connector connector = null;// 查询条件的连接符(and,or)
			String operator = null;// 查询条件的运算符(=,>,< 等等)

			Map<String, StringBuilder> conditions = new HashMap<String, StringBuilder>();// 分组查询条件
			StringBuilder condition;// 表示一个查询条件
			if (bizObject.getQueryFields() != null) {
				for (QueryField queryField : (List<QueryField>) bizObject.getQueryFields()) {
					code = queryField.getCode().toUpperCase();
					paramValue = parameterMap.get(code);
					if (paramValue == null || StringUtils.isEmpty(paramValue)) {
						// 使用默认参数值
						paramValue = queryField.getDefaultValue();
					}
					defaultClause = queryField.getDefaultClause();
					if ((paramValue == null || StringUtils.isEmpty(paramValue)) && (defaultClause == null || StringUtils.isEmpty(defaultClause))) {
						continue;// 参数值(默认参数值)和默认自定义查询语句都不存在，则忽略此参数
					}
					clause = queryField.getClause();
					group = queryField.getGroup();
					connector = queryField.getConnector();
					condition = new StringBuilder();
					if (paramValue != null && !StringUtils.isEmpty(paramValue)) {
						// 参数存在
						if (clause == null || StringUtils.isEmpty(clause)) {
							// 动态拼接
							operator = queryField.getOperator();
							condition.append(connector).append(" ").append(code).append(operator).append("'").append(paramValue).append("'");
						} else {
							// 使用自定义语句
							condition.append(connector).append(" ").append(clause.replaceAll("\\?", paramValue));
						}
					} else {
						// 参数值不存在，使用默认的自定义语句
						condition.append(connector).append(" ").append(defaultClause);
					}

					if (conditions.get(group) == null) {
						conditions.put(group, condition);
					} else {
						conditions.get(group).append(" ").append(condition);
					}
					if (logger.isDebugEnabled()) {
						logger.debug(code + "(" + group + ")" + "-----" + paramValue);
					}
				}
			}
			condition = null;
			operator = null;
			connector = null;
			defaultClause = null;
			clause = null;
			paramValue = null;
			group = null;
			code = null;

			// 替换SQL中的#conditions#
			Set<Entry<String, StringBuilder>> set = conditions.entrySet();
			Iterator<Entry<String, StringBuilder>> it = set.iterator();
			Entry<String, StringBuilder> entry = null;
			while (it.hasNext()) {
				entry = it.next();
				sql = sql.replaceAll("#" + entry.getKey() + "#", entry.getValue().toString());
			}
			entry = null;
			it = null;
			set = null;
			conditions = null;

			// 如果没有有效的查询条件，需要替换sql中的#conditions#标记
			int beginIndex = 0;
			int endIndex = 0;
			while ((beginIndex = sql.indexOf("#", beginIndex)) != -1) {
				endIndex = sql.indexOf("#", beginIndex + 1);
				if (endIndex == -1) {
					throw new EasyUIDataLoadException(String.format("业务模型 %s[%s] 中数据查询语句 %s 条件占位符不完整！", bizObject.getName(), bizObject.getCode(), bizObject.getSelectSQL()));
				}
				sql = sql.substring(0, beginIndex) + sql.substring(endIndex + 1);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("[SQL]处理后：" + sql);
			}

			Page page = new Page();
			page.setItemsPerPage(itemsPerPage);
			page.setTargetPage(targetPage);
			page.setSql(sql);
			try {
				DML.query(page);
			} catch (ExceptionHandler e) {
				throw new EasyUIDataLoadException(e);
			}

			// 输出数据到客户端
			String tree = getParameter("tree");
			try {
				if ("true".equalsIgnoreCase(tree)) {
					// 树形展示
					List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
					JSONObject jsonObject = new JSONObject();
					for (Map<String, Object> map : (List<Map<String, Object>>) page.getResult()) {
						Map<String, Object> m = new HashMap<String, Object>();
						m.put("id", map.get("ID").toString());
						m.put("text", map.get("NAME").toString());
						if (map.get("LEAFSTATE") != null) {
							m.put("state", "open".equalsIgnoreCase(map.get("LEAFSTATE").toString()) ? "open" : "closed");
						} else {
							m.put("state", "closed");
						}
						m.put("attributes", map);
						list.add(m);
					}
					jsonObject.put("result", list);
					String s = jsonObject.toJSONString().substring(10);
					s = s.substring(0, s.length() - 1);
					output(s);
				} else {
					// 列表展示
					output(page.getJsonMapResult());
				}
			} catch (ExceptionHandler e) {
				throw new EasyUIDataLoadException(e);
			}

			page = null;
			sql = null;
			targetPage = null;
			itemsPerPage = null;
			bizCode = null;

		}

		// loadData后置动作 afterLoadData
		if (result == Interceptor.INCLUDE_AFTER || result == Interceptor.INCLUDE_ALL) {
			if (interceptor != null) {
				if (logger.isDebugEnabled()) {
					logger.debug(String.format("调用业务模型 %s[%s] 中拦截器类 %s 的 afterLoadData 方法", bizObject.getName(), bizObject.getCode(), bizObject.getInterceptor()));
				}
				try {
					interceptor.afterLoadData(bizObject, parameterMap, getServerInterface());
				} catch (ExceptionHandler e) {
					throw new EasyUIDataLoadException(e);
				}
			}
		}

		parameterMap = null;
		bizObject = null;
	}

	/**
	 * 默认预新增方法
	 * 
	 * @return
	 * @throws ExceptionHandler
	 */
	public String preAdd() throws ExceptionHandler {
		String bizCode = getParameter("bizCode");

		BizObject bizObject = BizObjectContainer.get(bizCode);
		if (bizObject == null) {
			throw new ExceptionHandler("未发现业务模型：" + bizCode);
		}

		Map<String, String> parameterMap = getParameterMap();

		// 清空业务字段的value值
		bizObject.clearFields();

		// 初始化数据
		service.preAdd(bizObject, parameterMap, getServerInterface());

		setAttribute("bizObject", bizObject);

		String target = bizObject.getAddPage();

		parameterMap = null;
		bizObject = null;
		bizCode = null;

		if (target != null && !StringUtils.isEmpty(target)) {
			if (GlobalParameter.PAGES.containsKey(target)) {
				return (String) GlobalParameter.PAGES.get(target);
			} else {
				return target;
			}
		} else {
			return GlobalParameter.ADD;
		}
	}

	/**
	 * 默认新增方法
	 * 
	 * @return
	 * @throws ExceptionHandler
	 */
	@SuppressWarnings("unchecked")
	public void add() throws ExceptionHandler {
		String bizCode = getParameter("bizCode");

		Map<String, String> parameterMap = getParameterMap();
		service.add(parameterMap, getServerInterface());

		JSONObject json = new JSONObject();
		json.put("parameters", parameterMap);

		packingMessage(json, parameterMap);

		output(json.toJSONString());

		json = null;
		parameterMap = null;
	}

	/**
	 * 包装消息
	 * 
	 * @param json
	 * @param parameterMap
	 */
	@SuppressWarnings("unchecked")
	public void packingMessage(JSONObject json, Map<String, String> parameterMap) {
		// 错误消息
		if (parameterMap.get(GlobalParameter.MESSAGE_ERROR) != null) {
			json.put(GlobalParameter.MESSAGE_ERROR, parameterMap.get(GlobalParameter.MESSAGE_ERROR));
			parameterMap.remove(GlobalParameter.MESSAGE_ERROR);
		} else {
			json.put(GlobalParameter.MESSAGE_ERROR, "");
		}
		// 警告消息
		if (parameterMap.get(GlobalParameter.MESSAGE_WARNING) != null) {
			json.put(GlobalParameter.MESSAGE_WARNING, parameterMap.get(GlobalParameter.MESSAGE_WARNING));
			parameterMap.remove(GlobalParameter.MESSAGE_WARNING);
		} else {
			json.put(GlobalParameter.MESSAGE_WARNING, "");
		}
		// 一般消息
		if (parameterMap.get(GlobalParameter.MESSAGE_INFO) != null) {
			json.put(GlobalParameter.MESSAGE_INFO, parameterMap.get(GlobalParameter.MESSAGE_INFO));
			parameterMap.remove(GlobalParameter.MESSAGE_INFO);
		} else {
			json.put(GlobalParameter.MESSAGE_INFO, "");
		}
	}

	/**
	 * 默认预修改方法
	 * 
	 * @return
	 * @throws ExceptionHandler
	 */
	public String preMod() throws ExceptionHandler {
		String bizCode = getParameter("bizCode");

		BizObject bizObject = BizObjectContainer.get(bizCode);
		if (bizObject == null) {
			throw new ExceptionHandler("未发现业务模型：" + bizCode);
		}

		Map<String, String> parameterMap = getParameterMap();

		// 清空业务字段的value值
		bizObject.clearFields();

		// 准备数据
		service.preMod(bizObject, parameterMap, getServerInterface());

		setAttribute("bizObject", bizObject);

		String target = bizObject.getModPage();

		parameterMap = null;
		bizCode = null;
		bizObject = null;

		if (target != null && !StringUtils.isEmpty(target)) {
			if (GlobalParameter.PAGES.containsKey(target)) {
				return (String) GlobalParameter.PAGES.get(target);
			} else {
				return target;
			}
		} else {
			return GlobalParameter.MOD;
		}
	}

	/**
	 * 默认修改方法
	 * 
	 * @return
	 * @throws ExceptionHandler
	 */
	@SuppressWarnings("unchecked")
	public void mod() throws ExceptionHandler {
		String bizCode = getParameter("bizCode");

		Map<String, String> parameterMap = getParameterMap();
		service.mod(parameterMap, getServerInterface());

		JSONObject json = new JSONObject();
		json.put("parameters", parameterMap);

		packingMessage(json, parameterMap);

		output(json.toJSONString());

		json = null;
		parameterMap = null;
	}

	/**
	 * 默认修改方法
	 * 
	 * @return
	 * @throws ExceptionHandler
	 */
	@SuppressWarnings("unchecked")
	public void del() throws ExceptionHandler {
		String bizCode = getParameter("bizCode");

		Map<String, String> parameterMap = getParameterMap();
		service.del(parameterMap, getServerInterface());

		JSONObject json = new JSONObject();
		json.put("parameters", parameterMap);

		packingMessage(json, parameterMap);

		output(json.toJSONString());

		json = null;
		parameterMap = null;
	}

	/**
	 * 默认查看方法
	 * 
	 * @return
	 * @throws ExceptionHandler
	 */
	public String view() throws ExceptionHandler {
		String bizCode = getParameter("bizCode");

		BizObject bizObject = BizObjectContainer.get(bizCode);
		if (bizObject == null) {
			throw new ExceptionHandler("未发现业务模型：" + bizCode);
		}

		Map<String, String> parameterMap = getParameterMap();

		// 清空业务字段的value值
		bizObject.clearFields();

		// 准备数据
		service.view(bizObject, parameterMap, getServerInterface());

		setAttribute("bizObject", bizObject);

		String target = bizObject.getViewPage();

		parameterMap = null;
		bizCode = null;
		bizObject = null;

		if (target != null && !StringUtils.isEmpty(target)) {
			if (GlobalParameter.PAGES.containsKey(target)) {
				return (String) GlobalParameter.PAGES.get(target);
			} else {
				return target;
			}
		} else {
			return GlobalParameter.VIEW;
		}
	}

	/**
	 * 业务对象选择 供 业务字段模板BDSelector调用
	 * 
	 * @throws ExceptionHandler
	 */
	public String choose() throws ExceptionHandler {
		String fieldTemplateCode = getParameter("fieldTemplateCode");
		FieldTemplate fieldTemplate = FieldTemplateContainer.get(fieldTemplateCode);
		if (fieldTemplate == null) {
			throw new ExceptionHandler("字段模板 " + fieldTemplateCode + " 不存在！");
		}
		setAttribute("fieldTemplate", fieldTemplate);

		// 解析引用的业务模型对象(如果有)
		BizObject bizObject = BizObjectContainer.get(fieldTemplate.getBizCode());
		if (bizObject != null) {
			setAttribute("bizObject", bizObject);
		}
		bizObject = null;

		String target = fieldTemplate.getUrl();

		fieldTemplate = null;

		if (target != null && !StringUtils.isEmpty(target)) {
			if (GlobalParameter.PAGES.containsKey(target)) {
				return (String) GlobalParameter.PAGES.get(target);
			} else {
				return target;
			}
		} else {
			return GlobalParameter.CHOOSE;
		}
	}

	/**
	 * 获取文件
	 * 
	 * @throws ExceptionHandler
	 */
	public void getFile() throws ExceptionHandler {
		String path = getParameter("path");
		boolean issuccess = false;
		if (!StringUtils.isEmpty(path)) {
			String[] fileInfo = path.split(":");
			if (fileInfo.length == 2) {
				downloadFile(fileInfo[1], fileInfo[0]);
				issuccess = true;
			}
		}

		if (!issuccess) {
			sendRedirect(getContextPath() + "/filenotfound.jsp");
		}
	}
}
